package com.ruoyi.app.business.register;

import cn.hutool.core.collection.CollUtil;
import com.ruoyi.app.business.account.LaborAccountBusiness;
import com.ruoyi.app.business.code.CheckCodeBusiness;
import com.ruoyi.app.business.code.InviteCodeBusiness;
import com.ruoyi.app.company.CompanyBusiness;
import com.ruoyi.app.config.util.UserUtil;
import com.ruoyi.app.converter.CompanyConverter;
import com.ruoyi.app.converter.UserConverter;
import com.ruoyi.app.domain.register.DemanderRegister;
import com.ruoyi.app.domain.register.LaborRegister;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.service.company.entity.CompanyEntity;
import com.ruoyi.service.score.service.LaborScoreService;
import com.ruoyi.service.user.entity.LaborExtEntity;
import com.ruoyi.service.user.entity.UserEntity;
import com.ruoyi.service.user.enums.UserStatusEnum;
import com.ruoyi.service.user.enums.UserTypeEnum;
import com.ruoyi.service.user.model.UserInfoModel;
import com.ruoyi.service.user.service.LaborExtService;
import com.ruoyi.service.user.service.UserService;
import java.time.LocalDateTime;
import java.util.List;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * <p>
 * 作用：注册信息相关服务
 * </p>
 *
 * @author Zane
 * @since 2025-10-03 21:55
 */

@Slf4j
@Component
public class RegisterBusiness {

  @Resource
  private UserService userService;
  @Resource
  private LaborExtService laborExtService;
  @Resource
  private LaborScoreService laborScoreService;
  @Resource
  private CompanyBusiness companyBusiness;
  @Resource
  private TransactionTemplate transactionTemplate;
  @Resource
  private CheckCodeBusiness checkCodeBusiness;
  @Resource
  private InviteCodeBusiness inviteCodeBusiness;
  @Resource
  private LaborAccountBusiness laborAccountBusiness;

  /**
   * 项目方注册
   *
   * @param demanderRegister 项目方注册信息
   */
  public void registerDemander(DemanderRegister demanderRegister) {
    //校验
    checkDemander(demanderRegister);
    final String user_name = UserTypeEnum.DEMANDER_USER.userNameByPhone(
        demanderRegister.getLinkPhone());
    //转换项目方信息和公司信息
    final CompanyEntity companyEntity = CompanyConverter.INSTANCE.toCompanyEntity(demanderRegister);
    final UserEntity userEntity = UserConverter.INSTANCE.toUserEntity(demanderRegister);
    userEntity
        //项目方默认通过
        .setStatus(UserStatusEnum.PASSED.getCode())
        .setUserName(user_name)
        .setUserType(UserTypeEnum.DEMANDER_USER.getCode())
        .setCreateBy(user_name)
        .setCreateTime(LocalDateTime.now())
        .setUpdateBy(user_name)
        .setUpdateTime(LocalDateTime.now());
    //补充必要信息
    transactionTemplate.executeWithoutResult(status -> {
      userService.save(userEntity);
      companyEntity.setCreateBy(userEntity.getUserId())
          .setCreateTime(LocalDateTime.now())
          .setUpdateBy(userEntity.getUserId())
          .setUpdateTime(LocalDateTime.now());
      companyEntity.setManager(userEntity.getUserId());
      companyBusiness.saveCompany(companyEntity);
    });
  }


  /**
   * 劳务方注册
   *
   * @param laborRegister 劳务方注册信息
   */
  public void registerLabor(LaborRegister laborRegister) {

    //校验
    checkLaborInfo(laborRegister);
    inviteCodeBusiness.checkInviteCode(laborRegister.getInviteCode());
    //抓换成用户信息和劳务信息
    final UserEntity userEntity = UserConverter.INSTANCE.toUserEntity(laborRegister);
    //补充必要信息
    userEntity
        //默认审核通过,走邀请码校验,和封号处理
        // 开启审核
        //.setStatus(UserStatusEnum.PASSED.getCode())
        .setUserType(UserTypeEnum.LABOR_USER.getCode())
        .setCreateBy(userEntity.getUserName())
        .setCreateTime(LocalDateTime.now())
        .setUpdateBy(userEntity.getUserName())
        .setUpdateTime(LocalDateTime.now());
    final LaborExtEntity laborExtEntity = UserConverter.laborExtConverter.toLaborExtEntity(
        laborRegister);
    laborExtEntity.setCreateBy(userEntity.getUserName())
        .setCreateTime(LocalDateTime.now())
        .setUpdateBy(userEntity.getUserName())
        .setUpdateTime(LocalDateTime.now());
    transactionTemplate.executeWithoutResult(status -> {
      userService.save(userEntity);
      laborExtEntity.setUserId(userEntity.getUserId());
      laborExtService.save(laborExtEntity);
      laborScoreService.initLaborScore(userEntity);
      laborAccountBusiness.initLaborAccount(userEntity);
      inviteCodeBusiness.useInviteCode(laborRegister.getInviteCode(), userEntity.getUserId());
    });
  }

  public UserInfoModel getLoginUserInfo() {
    return UserUtil.getLoginUserMasking();
  }

  private void checkDemander(DemanderRegister demanderRegister) {
    checkCodeBusiness.checkCode(demanderRegister.getLinkPhone(), demanderRegister.getCheckCode());
    checkUserNameAndPhone(
        UserTypeEnum.DEMANDER_USER.userNameByPhone(demanderRegister.getLinkPhone()),
        demanderRegister.getLinkPhone(), UserTypeEnum.DEMANDER_USER);
    //校验公司统一社会信用码,是否已经注册
    if (companyBusiness.companyExist(demanderRegister.getUsci())) {
      throw new ServiceException("公司已注册,请联系管理员");
    }
    ;

  }

  private void checkLaborInfo(LaborRegister laborReg) {
    // 补充用户名
    if (StringUtils.isBlank(laborReg.getUserName())) {
      laborReg.setUserName(UserTypeEnum.LABOR_USER.userNameByPhone(laborReg.getPhone()));
    }
    checkCodeBusiness.checkCode(laborReg.getPhone(), laborReg.getCheckCode());
    checkUserNameAndPhone(laborReg.getUserName(), laborReg.getPhone(), UserTypeEnum.LABOR_USER);
  }

  /**
   * 验证用户名和手机号是否被占用
   *
   * @param userName     用户名
   * @param phone        手机号
   * @param userTypeEnum 用户类型
   */
  private void checkUserNameAndPhone(String userName, String phone, UserTypeEnum userTypeEnum) {
    //校验用户名或者手机号,当前用户类型下是否已经被占用
    final List<UserEntity> userList = userService.getByUserNameOrMobile(userName, phone,
        userTypeEnum.getCode());
    if (CollUtil.isNotEmpty(userList)) {
      if (userList.stream().anyMatch(user -> phone.equals(user.getPhone()))) {
        throw new RuntimeException("手机号已存在,请联系平台");
      }
      //理论上会出现,实际中概率很低
      if (userList.stream().anyMatch(user -> user.getUserName().equals(userName))) {
        throw new RuntimeException("手机号已存在,请联系平台");
      }
    }
  }


}
